<template>
  <el-card>
    <!-- 
      树形数据与懒加载：
      :row-key="getRowKey" 树形数据显示必填 行数据的 Key
      lazy 是否懒加载子节点数据 默认true
      :load="load" 懒加载时触发的函数
      渲染嵌套数据的配置选项
      :tree-props="{                    table表格中data数据中对象的字段
        children: 'children',           子节点具体的内容
         hasChildren: 'hasChildren'     代表当前节点有子节点
      }"
     -->
    <el-table
      border
      :data="category1List"
      :row-key="getRowKey"
      lazy
      :load="load"
      :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
      ref="tableRef"
    >
      <el-table-column
        label="分类ID"
        prop="id"
        align="center"
        width="150"
      ></el-table-column>
      <el-table-column label="分类名称" prop="name" />
      <el-table-column align="center" width="250">
        <!-- 自定义表头 -->
        <template #header>
          <el-input
            placeholder="按Enter键添加一级分类"
            @keyup.enter="addCategory1"
            v-model="categoryName"
          />
        </template>
        <template v-slot="{ row }">
          <el-button
            size="small"
            :icon="Plus"
            type="primary"
            title="添加子分类"
            @click="showAddCategory(row)"
            :disabled="row.level === 3"
            v-permission="'btn.Category.add'"
          />
          <el-button
            size="small"
            :icon="Edit"
            type="warning"
            title="修改分类"
            @click="showUpdateCategory(row)"
            v-permission="'btn.Category.update'"
          />
          <el-button
            size="small"
            type="danger"
            :icon="Delete"
            title="删除分类"
            v-permission="'btn.Category.remove'"
            @click="deleteCategory(row)"
          />
        </template>
      </el-table-column>
    </el-table>
    <!-- 
      更新和添加都是同一个对话框
      二级和三级的操作也是同一个对话框
    -->
    <el-dialog
      :title="`${isUpdateCategory ? '更新' : '添加'}${
        category.level === 1 ? '二级' : '三级'
      }分类`"
      v-model="dialogFormVisible"
      align-center
    >
      <el-form>
        <el-form-item label="分类名称">
          <!-- 修改的输入框 -->
          <el-input
            placeholder="请输入分类名称"
            v-if="isUpdateCategory"
            v-model="updatedCategory.name"
          ></el-input>
          <!-- 添加的输入框 -->
          <el-input
            v-else
            placeholder="请输入分类名称"
            v-model="categoryName"
          ></el-input>
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="cancel">取消</el-button>
          <!-- 确定按钮：更新，添加 -->
          <el-button
            type="primary"
            v-if="isUpdateCategory"
            @click="updateCategory"
          >
            确认
          </el-button>
          <el-button type="primary" @click="addCategory" v-else>
            确认
          </el-button>
        </span>
      </template>
    </el-dialog>
  </el-card>
</template>

<script lang="ts">
export default {
  name: "XCategory",
};
</script>

<script lang="ts" setup>
import { Plus, Edit, Delete } from "@element-plus/icons-vue";
import { ref, onMounted } from "vue";
import { ElMessage } from "element-plus";
import {
  getCategory1ListApi,
  getCategory2ListApi,
  getCategory3ListApi,
  addCategory1Api,
  addCategory2Api,
  addCategory3Api,
  updateCategory1Api,
  updateCategory2Api,
  updateCategory3Api,
  removeCategory1Api,
  removeCategory2Api,
  removeCategory3Api,
} from "@/api/product/category";
import type {
  CategoryList,
  CategoryItem,
} from "@/api/product/model/categoryModel";
const category1List = ref<CategoryList>([]);
// const maps = new Map()
// 获取一级分类
const getCategory1List = async () => {
  const res = await getCategory1ListApi();
  // 给数据添加两个属性
  category1List.value = res.map((category) => {
    return {
      ...category,
      hasChildren: true, // 代表有子节点 一级分类的子节点是二级分类
      level: 1, // 表示一级分类
    };
  });
};

// 一挂载就获取一级分类
onMounted(getCategory1List);

// 函数的返回值就是table的key值
const getRowKey = (row: CategoryItem) => {
  return row.level + "-" + row.id;
};
let maps = ref(new Map());
// 懒加载函数
const load = async (
  row: CategoryItem,
  treeNode: unknown,
  resolve: (date: CategoryItem[]) => void
) => {
  // load函数中将单行数据保存
  maps.value.set(row.id, { row, treeNode, resolve });
  if (row.level === 1) {
    // 点击一级分类，展开获取二级分类数据
    const res = await getCategory2ListApi(row.id);
    resolve(
      res.map((category) => {
        return {
          ...category,
          hasChildren: true, // 二级分类的子节点是三级分类
          level: 2,
        };
      })
    );
  } else if (row.level === 2) {
    // 点击二级分类，展开获取三级分类数据
    const res = await getCategory3ListApi(row.id);
    resolve(
      res.map((category) => {
        return {
          // 三级没有子节点
          ...category,
          level: 3,
        };
      })
    );
  }
};

const categoryName = ref("");
// 添加一级分类
const addCategory1 = async () => {
  if (!categoryName.value) return;
  await addCategory1Api(categoryName.value);
  ElMessage.success("添加一级分类成功~");
  getCategory1List();
  categoryName.value = "";
};

const dialogFormVisible = ref(false);
const category = ref<CategoryItem>({
  id: 0,
  name: "",
});
// 显示添加分类
const showAddCategory = (row: CategoryItem) => {
  dialogFormVisible.value = true;
  category.value = row;
};
const tableRef = ref();
// 添加二级/三级分类
const addCategory = async () => {
  if (!categoryName.value) return;
  if (category.value.level === 1) {
    await addCategory2Api(category.value.id, categoryName.value);
  } else if (category.value.level === 2) {
    await addCategory3Api(category.value.id, categoryName.value);
  }
  // 问题：table懒加载子节点数据添加成功，页面不更新
  // 解决方案：
  // 1.给table绑定ref
  // 2.找到对应的数据，将loaded改成false，代表这个数据没有被加载
  tableRef.value.store.states.treeData.value[
    `${category.value.level}-${category.value.id}`
  ].loaded = false;
  // 3.重新触发load，加载渲染相应的子节点
  tableRef.value.store.loadOrToggle(category.value);

  ElMessage.success(
    `添加${category.value.level === 1 ? "二级" : "三级"}分类成功~`
  );
  cancel();
};
// 关闭对话框
const cancel = () => {
  dialogFormVisible.value = false;
  categoryName.value = "";
};
const isUpdateCategory = ref(false);
const updatedCategory = ref<CategoryItem>({
  id: 0,
  name: "",
});
// 显示修改分类
const showUpdateCategory = (row: CategoryItem) => {
  isUpdateCategory.value = true;
  dialogFormVisible.value = true;
  // 原数据
  category.value = row;
  // 与原数据一样的更新数据,为了不改变原数据
  updatedCategory.value = {
    ...row,
  };
};
// 更新一级/二级/三级分类
const updateCategory = async () => {
  if (!category.value.name) return;
  if (category.value.level === 1) {
    // 一级分类更新一级分类
    await updateCategory1Api(category.value.id, category.value.name);
  } else if (category.value.level === 2) {
    // 二级分类更新二级分类
    await updateCategory2Api(category.value.id, category.value.name);
  } else {
    // 三级分类更新三级分类
    await updateCategory3Api(category.value.id, category.value.name);
  }
  category.value.name = updatedCategory.value.name;
  ElMessage.success("更新分类成功~");
  cancel();
};

// 删除分类
const deleteCategory = async (row: CategoryItem) => {
  // console.log(row.id);
  // category.value = row;

  if (row.level === 1) {
    await removeCategory1Api(row.id);
    getCategory1List();
  } else if (row.level === 2) {
    await removeCategory2Api(row.id);
  } else {
    await removeCategory3Api(row.id);
  }
  // 2.找到对应的数据，将loaded改成false，代表这个数据没有被加载
  tableRef.value.store.states.treeData.value[
    `${category.value.level}-${category.value.id}`
  ].loaded = false;
  // 3.重新触发load，加载渲染相应的子节点
  tableRef.value.store.loadOrToggle(category.value);
  ElMessage.success("删除分类成功~");
};
</script>

<style scoped></style>
